package com.javafactroy.kunlong.bip.icp.message.dxp.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.javafactroy.kunlong.bip.icp.common.consts.IConfig;
import com.javafactroy.kunlong.bip.icp.common.consts.IMsgType;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import com.javafactroy.kunlong.bip.icp.message.base.base.Message;
import com.javafactroy.kunlong.bip.icp.message.base.iface.IMessage;
import com.javafactroy.kunlong.bip.icp.message.dxp.app.HandshakeMessage;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

@Data
@ToString()
@Slf4j
public class DxpMsg extends Message implements IMessage {

    IConfig.INettyConst.MSG_State msgState;

    int totalLen;
    DxpHeader header;
    DxpBody body;

    public DxpMsg() {
        this.header = new DxpHeader();
        this.body = new DxpBody();
    }


    @Override
    public byte[] encode() {

        byte[] bytesBody = this.body.encode();
        totalLen = DxpHeader.MSG_HEADER_LEN + bytesBody.length;
        header.setMsgLen(totalLen);
        byte[] bytesHeader = header.encode();

        ByteBuffer byteBuffer = ByteBuffer.allocate(totalLen);
        byteBuffer.put(bytesHeader);
        byteBuffer.put(bytesBody);
        byteBuffer.rewind();
        log.info("encode totalLen ={}",totalLen);
        byte[] bytes= byteBuffer.array();
        log.info("{}", ByteBufUtil.prettyHexDump(Unpooled.wrappedBuffer(bytes)));
        return bytes;

    }

    @Override
    public ByteBuf encode2ByteBuf() {
        return Unpooled.wrappedBuffer(encode());
    }

    @Override
    public void decode(byte[] buf) {

        if (buf.length >= DxpHeader.MSG_HEADER_LEN) {
            header.decode(buf);
            if (buf.length >= header.getMsgLen()) {
                ByteBuffer bf = ByteBuffer.wrap(buf);
                int bodyLen = header.getMsgLen() - DxpHeader.MSG_HEADER_LEN;
                byte[] bodys = new byte[bodyLen];
                bf.position(DxpHeader.MSG_HEADER_LEN);
                bf.get(bodys);
                body.decode(bodys);
            }

        }
    }

    public void decode(ByteBuffer buf) {
        buf.rewind();
        decode(buf.array());

    }


    @Override
    public void check() {

    }


    @Override
    public String getMessageId() {
        return String.valueOf(getHeader().getMsgId());
    }

    @Override
    public String getMsgType() {
        return ""+getHeader().getMsgType();
    }

    public void decodeLen(byte[] buf) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(buf);
        byteBuffer.order(ByteOrder.BIG_ENDIAN);
        this.totalLen = byteBuffer.getInt();
    }

    public static DxpMsg buildDxpMsg() {
        DxpMsg msg = buildMessage();
        msg.getHeader().setMsgType(IMsgType.MsgType_Dxp_Stub_Default);
        return msg;
    }

    public static DxpMsg buildMessage() {

        DxpMsg msg = new DxpMsg();
        DxpHeader messageHeader = new DxpHeader();
        msg.setHeader(messageHeader);

        DxpBody body = new DxpBody();
        body.setBody("sz".getBytes());
        msg.setBody(body);

        return msg;
    }

    public static DxpMsg buildCloseMessage() {
        return buildMessage();
    }

    public static void main(String[] args) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(8);
        byteBuffer.order(ByteOrder.BIG_ENDIAN);
        byteBuffer.putInt(8);
        byteBuffer.put("ABCD".getBytes());
        byte[] ll = byteBuffer.array();
        System.out.println("1");
        DxpHeader mh = new DxpHeader();

        DxpMsg m = new DxpMsg();
        m.setHeader(mh);
        DxpBody mb = new DxpBody();
        mb.setBody("id=1123".getBytes());
        m.setBody(mb);
        byte[] br = m.encode();

        System.out.println(new String(br));
        DxpMsg mm = new DxpMsg  ();

        mm.decode(br);
        System.err.println(mm);

        HandshakeMessage hsm = new HandshakeMessage("BPM");
        byte[] hs = hsm.encode();
        System.out.println(new String(hs));
    }

    public String toJSONString() {
        return JSON.toJSONString(this, SerializerFeature.PrettyFormat);
    }


}
